'''
Created on Sep 7, 2012

@author: petrina
'''
from link_indicator import Link_indicator
import logging
import math

class Total_correlation_coefficient(Link_indicator):
    '''
    Calculates the overall correlation coefficient (using aggregated fcd-data).
    
    Formula for calculating the indicator: 
        c_i = a_i/sqrt(b_i * g_i)
        a_i = n * sum(x_i_d*y_i_d) - sum(x_i_d)*sum(y_i_d) 
        b_i = n * sum(x_i_d^2 - sum(x_i_d)^2)
        g_i = n * sum(y_i_d^2 - sum(y_i_d)^2)
            where
              - c_i  ... correlation coefficient for the time interval i
              - x_i_d  ... analyzed data on the day d and interval i
              - y_i_d  ... reference data on the day d and interval i
              - n ... number of days
    unit: index value
    '''


    def __init__(self, link):
        '''        
        @param link: Link-object (containing valid records and reference) 
        '''
        
        Link_indicator.__init__(self, link)
        self._name = 'Total Correlation Coefficient'
        self._mr_name =  'total_corr_coef'
        self._unit = 'index'
        #self.unit.__doc__ = 'index value'

        self._create_title(link.id, link.direction)
        
        logging.debug("Total_correlation_coefficient: created new Correlation_coefficient")
        
    #----------------------public methods of the class-------------------------

    def calculate(self):
        '''
        Calculates the correlation coefficient with the fleet-data and the reference data.
        
        @return: list of Result_values for the correlation coefficient for every time interval
        '''
        
        logging.info("Total_correlation_coefficient: staring to calculate the correlation coefficient")
        
        value = None
        
        # sum of values on a day     
        sum_x = 0  
        sum_y = 0
        sum_xy = 0
        sum_xx = 0
        sum_yy =0  
                         
        # number of values
        n = 0
        
        # for all intervals
        for i in range(self._intervals):
            ref_data = self._link.reference[i]
            rec_data = self._link.records[i]
            
            if len(ref_data) > 0 and len(rec_data) > 0:            
                
                min_time = min(rec_data.begintime, ref_data.begintime)
                max_time = max(rec_data.endtime, ref_data.endtime)
                
                x = rec_data.create_value_list(min_time, max_time, attribute = 'speed') 
                y = ref_data.create_value_list(min_time, max_time, attribute = 'speed') 
                
                for j in range(len(y)):           
                    if y[j] is not None and x[j] is not None:
                        sum_x += x[j]
                        sum_y += y[j]
                        sum_xy += x[j] * y[j]
                        sum_xx += x[j] * x[j]
                        sum_yy += y[j] * y[j]
                        n += 1
                
        # no division by zero    
        if n > 0:
            # formula for correlation coefficient
            denominator = math.sqrt((n * sum_xx - sum_x * sum_x)*(n * sum_yy - sum_y * sum_y))
            if denominator != 0:
                value = (n * sum_xy - sum_x * sum_y)/denominator
                
        self._values = [value, value]
        self._times = [self._link.records.begintime, self._link.records.endtime]

        logging.debug("Total_correlation_coefficient: finished calculating the correlation coefficient")

        return self._values


    def plot(self, plotobject):
        '''
        the plot shows begin and endtime and a constant function (with the calculated value)
        '''
        
        self._plot_period(plotobject, fmt='-')